#![crate_id="cargo-compile"]
#![allow(deprecated_owned_vector)]
-extern crate serialize;
-extern crate hammer;
extern crate cargo;
-use std::vec::Vec;
-use serialize::{Decodable};
-use hammer::{FlagDecoder,FlagConfig,FlagConfiguration,HammerError};
-use std::io;
-use std::io::BufReader;
-use std::io::process::{Process,ProcessExit,ProcessOutput,InheritFd,ProcessConfig};
-use cargo::{ToCargoError,CargoResult};
-
-#[deriving(Decodable)]
-struct Options {
- manifest_path: ~str
-}
-
-impl FlagConfig for Options {
- fn config(_: Option<Options>, c: FlagConfiguration) -> FlagConfiguration { c }
-}
+use cargo::ops::cargo_compile::compile;
fn main() {
match compile() {
Ok(_) => return
}
}
-
-fn compile() -> CargoResult<()> {
- let options = try!(flags::<Options>());
- let manifest_bytes = try!(read_manifest(options.manifest_path).to_cargo_error(~"Could not read manifest", 1));
-
- call_rustc(~BufReader::new(manifest_bytes.as_slice()))
-}
-
-fn flags<T: FlagConfig + Decodable<FlagDecoder, HammerError>>() -> CargoResult<T> {
- let mut decoder = FlagDecoder::new::<T>(std::os::args().tail());
- Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1)
-}
-
-fn read_manifest(manifest_path: &str) -> CargoResult<Vec<u8>> {
- Ok((try!(exec_with_output("cargo-read-manifest", [~"--manifest-path", manifest_path.to_owned()], None))).output)
-}
-
-fn call_rustc(mut manifest_data: ~Reader:) -> CargoResult<()> {
- let data: &mut Reader = manifest_data;
- try!(exec_tty("cargo-rustc", [], Some(data)));
- Ok(())
-}
-
-fn exec_with_output(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult<ProcessOutput> {
- Ok((try!(exec(program, args, input, |_| {}))).wait_with_output())
-}
-
-fn exec_tty(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult<ProcessExit> {
- Ok((try!(exec(program, args, input, |config| {
- config.stdout = InheritFd(1);
- config.stderr = InheritFd(2);
- }))).wait())
-}
-
-fn exec(program: &str, args: &[~str], input: Option<&mut Reader>, configurator: |&mut ProcessConfig|) -> CargoResult<Process> {
- let mut config = ProcessConfig::new();
- config.program = program;
- config.args = args;
- configurator(&mut config);
-
- println!("Executing {} {}", program, args);
-
- let mut process = try!(Process::configure(config).to_cargo_error(~"Could not configure process", 1));
-
- input.map(|mut reader| io::util::copy(&mut reader, process.stdin.get_mut_ref()));
-
- Ok(process)
-}
#![allow(deprecated_owned_vector)]
extern crate cargo;
-extern crate hammer;
-extern crate serialize;
-extern crate toml;
-use hammer::FlagConfig;
-use serialize::Decoder;
-use toml::from_toml;
-use cargo::core;
-use cargo::{CargoResult,ToCargoError,execute_main_without_stdin};
-use std::path::Path;
-
-#[deriving(Decodable,Encodable,Eq,Clone,Ord)]
-struct SerializedManifest {
- project: ~core::Project,
- lib: Option<~[SerializedLibTarget]>,
- bin: Option<~[SerializedExecTarget]>
-}
-
-#[deriving(Decodable,Encodable,Eq,Clone,Ord)]
-pub struct SerializedTarget {
- name: ~str,
- path: Option<~str>
-}
-
-pub type SerializedLibTarget = SerializedTarget;
-pub type SerializedExecTarget = SerializedTarget;
-
-
-#[deriving(Decodable,Eq,Clone,Ord)]
-struct ReadManifestFlags {
- manifest_path: ~str
-}
-
-impl FlagConfig for ReadManifestFlags {}
+use cargo::execute_main_without_stdin;
+use cargo::ops::cargo_read_manifest::execute;
fn main() {
execute_main_without_stdin(execute);
}
-
-fn execute(flags: ReadManifestFlags) -> CargoResult<Option<core::Manifest>> {
- let manifest_path = flags.manifest_path;
- let root = try!(toml::parse_from_file(manifest_path.clone()).to_cargo_error(format!("Couldn't parse Toml file: {}", manifest_path), 1));
-
- let toml_manifest = try!(from_toml::<SerializedManifest>(root.clone()).to_cargo_error(|e: toml::Error| format!("{}", e), 1));
-
- let (lib, bin) = normalize(&toml_manifest.lib, &toml_manifest.bin);
-
- Ok(Some(core::Manifest {
- root: try!(Path::new(manifest_path.clone()).dirname_str().to_cargo_error(format!("Could not get dirname from {}", manifest_path), 1)).to_owned(),
- project: toml_manifest.project,
- lib: lib,
- bin: bin
- }))
-}
-
-fn normalize(lib: &Option<~[SerializedLibTarget]>, bin: &Option<~[SerializedExecTarget]>) -> (~[core::LibTarget], ~[core::ExecTarget]) {
- fn lib_targets(libs: &[SerializedLibTarget]) -> ~[core::LibTarget] {
- let l = &libs[0];
- let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name));
- ~[core::LibTarget { path: path, name: l.name.clone() }]
- }
-
- fn bin_targets(bins: &[SerializedExecTarget], default: |&SerializedExecTarget| -> ~str) -> ~[core::ExecTarget] {
- bins.iter().map(|bin| {
- let path = bin.path.clone().unwrap_or_else(|| default(bin));
- core::ExecTarget { path: path, name: bin.name.clone() }
- }).collect()
- }
-
- match (lib, bin) {
- (&Some(ref libs), &Some(ref bins)) => {
- (lib_targets(libs.as_slice()), bin_targets(bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name)))
- },
- (&Some(ref libs), &None) => {
- (lib_targets(libs.as_slice()), ~[])
- },
- (&None, &Some(ref bins)) => {
- (~[], bin_targets(bins.as_slice(), |bin| format!("src/{}.rs", bin.name)))
- },
- (&None, &None) => {
- (~[], ~[])
- }
- }
-}
#![crate_id="cargo-rustc"]
#![allow(deprecated_owned_vector)]
-extern crate toml;
-extern crate hammer;
-extern crate serialize;
extern crate cargo;
-use std::os::args;
-use std::io;
-use std::io::process::{Process,ProcessConfig,InheritFd};
-use std::path::Path;
-use cargo::{CargoResult,CargoError,ToCargoError,NoFlags,execute_main};
-use cargo::core;
-
-/**
- cargo-rustc -- ...args
-
- Delegate ...args to actual rustc command
-*/
+use cargo::execute_main;
+use cargo::ops::cargo_rustc::execute;
fn main() {
execute_main(execute);
}
-
-fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult<Option<core::Manifest>> {
- let core::Manifest { root, lib, bin, .. } = manifest;
-
- let (crate_type, out_dir) = if lib.len() > 0 {
- ( ~"lib", lib[0].path )
- } else if bin.len() > 0 {
- ( ~"bin", bin[0].path )
- } else {
- return Err(CargoError::new(~"bad manifest, no lib or bin specified", 1));
- };
-
- let root = Path::new(root);
- let target = join(&root, ~"target");
-
- let args = [
- join(&root, out_dir),
- ~"--out-dir", target,
- ~"--crate-type", crate_type
- ];
-
- match io::fs::mkdir_recursive(&root.join("target"), io::UserRWX) {
- Err(_) => fail!("Couldn't mkdir -p"),
- Ok(val) => val
- }
-
- println!("Executing rustc {}", args.as_slice());
-
- let mut config = ProcessConfig::new();
- config.stdout = InheritFd(1);
- config.stderr = InheritFd(2);
- config.program = "rustc";
- config.args = args.as_slice();
-
- let mut p = try!(Process::configure(config).to_cargo_error(format!("Could not start process: rustc {}", args.as_slice()), 1));
-
- let status = p.wait();
-
- if status != std::io::process::ExitStatus(0) {
- fail!("Failed to execute")
- }
-
- Ok(None)
-}
-
-fn join(path: &Path, part: ~str) -> ~str {
- format!("{}", path.join(part).display())
-}
-use semver::Version;
+use core::package::NameVer;
-#[deriving(Clone,Eq,Show)]
+#[deriving(Eq,Clone,Show)]
pub struct Dependency {
- name: ~str,
- version: Vec<VersionReq>
-}
-
-#[deriving(Clone,Eq,Show)]
-pub struct VersionReq {
- parts: Vec<VersionOrd>
-}
-
-type VersionOrd = (Version, Vec<Ordering>);
-
-impl VersionReq {
- pub fn parse(req: &str) -> VersionReq {
- }
-
- /*
- pub fn new(version: Version, comparison: Vec<Ordering>) -> VersionReq {
- VersionReq { comparison: comparison, version: version }
- }
- */
-
- pub fn matches(&self, version: &Version) -> bool {
- /*
- let ordering = compare_versions(&self.version, version);
- self.comparison.iter().any(|ord| ordering == *ord)
- */
- false
- }
-}
-
-fn compare_versions(a: &Version, b: &Version) -> Ordering {
- if a == b {
- Equal
- } else if a.lt(b) {
- Less
- } else {
- Greater
- }
+ name: NameVer
}
impl Dependency {
pub fn new(name: &str) -> Dependency {
- Dependency { name: name.to_owned(), version: Vec::new() }
+ Dependency { name: NameVer::new(name.to_owned(), "1.0.0") }
}
- pub fn get_name<'a>(&'a self) -> &'a str {
- self.name.as_slice()
+ pub fn with_name_and_version(name: &str, version: &str) -> Dependency {
+ Dependency { name: NameVer::new(name, version) }
}
-}
-
-#[cfg(test)]
-mod tests {
- use super::VersionReq;
- use semver;
- use semver::Version;
- use hamcrest::{
- assert_that,
- Matcher,
- MatchResult,
- SelfDescribing
- };
- trait VersionReqExt {
- pub fn greater_than(version: Version) -> VersionReq {
- VersionReq::new(version, vec!(Greater))
- }
-
- pub fn equal_to(version: Version) -> VersionReq {
- VersionReq::new(version, vec!(Equal))
- }
- }
-
- impl VersionReqExt for VersionReq {}
-
- #[test]
- fn test_req_matches() {
- let req = VersionReq::new(semver::parse("2.0.0").unwrap(), vec!(Equal));
- //let req = greater_than(semver::parse("2.0.0").unwrap());
-
- assert_that(req, version_match("2.0.0"));
- }
-
- struct VersionMatch {
- version: ~str,
- }
-
- impl SelfDescribing for VersionMatch {
- fn describe(&self) -> ~str {
- format!("Requirement to match {}", self.version)
- }
- }
-
- impl Matcher<VersionReq> for VersionMatch {
- fn matches(&self, actual: VersionReq) -> MatchResult {
- match semver::parse(self.version) {
- None => Err(~"was not a valid semver version"),
- Some(ref version) => {
- if actual.matches(version) {
- Ok(())
- } else {
- Err(format!("{} did not match {}", version, actual))
- }
- }
- }
- }
- }
-
- fn version_match(str: &str) -> ~VersionMatch {
- ~VersionMatch { version: str.to_owned() }
+ pub fn get_name<'a>(&'a self) -> &'a str {
+ self.name.get_name()
}
-
}
+use core::package::NameVer;
/*
* TODO: Make all struct fields private
pub project: ~Project,
pub root: ~str,
pub lib: ~[LibTarget],
- pub bin: ~[ExecTarget]
+ pub bin: ~[ExecTarget],
+ pub dependencies: Vec<NameVer>
+}
+
+impl Manifest {
+ pub fn get_name_ver(&self) -> NameVer {
+ NameVer::new(self.project.name.as_slice(), self.project.version.as_slice())
+ }
+
+ pub fn get_path<'a>(&'a self) -> Path {
+ Path::new(self.root.as_slice())
+ }
}
#[deriving(Decodable,Encodable,Eq,Clone,Ord)]
-
-pub use self::dependency::Dependency;
pub use self::registry::{
- Registry,
- MemRegistry};
+ Registry,
+ MemRegistry
+};
pub use self::manifest::{
- Manifest,
- Project,
- LibTarget,
- ExecTarget};
+ Manifest,
+ Project,
+ LibTarget,
+ ExecTarget
+};
-pub use self::package::Package;
+pub use self::package::{
+ Package,
+ NameVer
+};
+
+pub use self::dependency::Dependency;
-mod dependency;
+pub mod source;
+pub mod package;
+pub mod dependency;
mod manifest;
-mod package;
mod registry;
mod resolver;
use std::vec::Vec;
+use semver;
+use semver::{Version,parse};
use core;
+use serialize::{Encodable,Encoder,Decodable,Decoder};
+
+#[deriving(Clone,Eq,Show,Ord)]
+pub struct NameVer {
+ name: ~str,
+ version: Version
+}
+
+impl NameVer {
+ pub fn new(name: &str, version: &str) -> NameVer {
+ println!("version: {}", version);
+ NameVer { name: name.to_owned(), version: semver::parse(version.to_owned()).unwrap() }
+ }
+
+ pub fn get_name<'a>(&'a self) -> &'a str {
+ self.name.as_slice()
+ }
+}
+
+impl<E, D: Decoder<E>> Decodable<D,E> for NameVer {
+ fn decode(d: &mut D) -> Result<NameVer, E> {
+ let vector: Vec<~str> = try!(Decodable::decode(d));
+ Ok(NameVer { name: vector.get(0).clone(), version: parse(vector.get(1).clone()).unwrap() })
+ }
+}
+
+impl<E, S: Encoder<E>> Encodable<S,E> for NameVer {
+ fn encode(&self, e: &mut S) -> Result<(), E> {
+ (vec!(self.name.clone(), self.version.to_str())).encode(e)
+ }
+}
/**
* Represents a rust library internally to cargo. This will things like where
--- /dev/null
+use core::package::NameVer;
+use CargoResult;
+
+pub struct PackagePath {
+ name: NameVer,
+ path: Path
+}
+
+impl PackagePath {
+ pub fn new(name: NameVer, path: Path) -> PackagePath {
+ PackagePath { name: name, path: path }
+ }
+}
+
+/**
+ * A Source finds and downloads remote packages based on names and
+ * versions.
+ */
+pub trait Source {
+ /**
+ * The update method performs any network operations required to
+ * get the entire list of all names, versions and dependencies of
+ * packages managed by the Source.
+ */
+ fn update(&self) -> CargoResult<()>;
+
+ /**
+ * The list method lists all names, versions and dependencies of
+ * packages managed by the source. It assumes that `update` has
+ * already been called and no additional network operations are
+ * required.
+ */
+ fn list(&self) -> CargoResult<Vec<NameVer>>;
+
+ /**
+ * The download method fetches the full package for each name and
+ * version specified.
+ */
+ fn download(&self, packages: Vec<NameVer>) -> CargoResult<()>;
+
+ /**
+ * The get method returns the Path of each specified package on the
+ * local file system. It assumes that `download` was already called,
+ * and that the packages are already locally available on the file
+ * system.
+ */
+ fn get(&self, packages: Vec<NameVer>) -> CargoResult<Vec<PackagePath>>;
+}
extern crate hammer;
extern crate serialize;
extern crate semver;
+extern crate toml;
#[cfg(test)]
extern crate hamcrest;
pub mod core;
pub mod util;
+pub mod sources;
+pub mod ops;
+
pub type CargoResult<T> = Result<T, CargoError>;
--- /dev/null
+/**
+ * Cargo compile currently does the following steps:
+ *
+ * All configurations are already injected as environment variables via the main cargo command
+ *
+ * 1. Read the manifest
+ * 2. Shell out to `cargo-resolve` with a list of dependencies and sources as stdin
+ * a. Shell out to `--do update` and `--do list` for each source
+ * b. Resolve dependencies and return a list of name/version/source
+ * 3. Shell out to `--do download` for each source
+ * 4. Shell out to `--do get` for each source, and build up the list of paths to pass to rustc -L
+ * 5. Call `cargo-rustc` with the results of the resolver zipped together with the results of the `get`
+ * a. Topologically sort the dependencies
+ * b. Compile each dependency in order, passing in the -L's pointing at each previously compiled dependency
+ */
+
+use std;
+use std::vec::Vec;
+use serialize::{Decodable};
+use hammer::{FlagDecoder,FlagConfig,FlagConfiguration,HammerError};
+use std::io;
+use std::io::BufReader;
+use std::io::process::{Process,ProcessExit,ProcessOutput,InheritFd,ProcessConfig};
+use {ToCargoError,CargoResult};
+
+#[deriving(Decodable)]
+struct Options {
+ manifest_path: ~str
+}
+
+impl FlagConfig for Options {
+ fn config(_: Option<Options>, c: FlagConfiguration) -> FlagConfiguration { c }
+}
+
+pub fn compile() -> CargoResult<()> {
+ let options = try!(flags::<Options>());
+ let manifest_bytes = try!(read_manifest(options.manifest_path).to_cargo_error(~"Could not read manifest", 1));
+
+ call_rustc(~BufReader::new(manifest_bytes.as_slice()))
+}
+
+fn flags<T: FlagConfig + Decodable<FlagDecoder, HammerError>>() -> CargoResult<T> {
+ let mut decoder = FlagDecoder::new::<T>(std::os::args().tail());
+ Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1)
+}
+
+fn read_manifest(manifest_path: &str) -> CargoResult<Vec<u8>> {
+ Ok((try!(exec_with_output("cargo-read-manifest", [~"--manifest-path", manifest_path.to_owned()], None))).output)
+}
+
+fn call_rustc(mut manifest_data: ~Reader:) -> CargoResult<()> {
+ let data: &mut Reader = manifest_data;
+ try!(exec_tty("cargo-rustc", [], Some(data)));
+ Ok(())
+}
+
+fn exec_with_output(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult<ProcessOutput> {
+ Ok((try!(exec(program, args, input, |_| {}))).wait_with_output())
+}
+
+fn exec_tty(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult<ProcessExit> {
+ Ok((try!(exec(program, args, input, |config| {
+ config.stdout = InheritFd(1);
+ config.stderr = InheritFd(2);
+ }))).wait())
+}
+
+fn exec(program: &str, args: &[~str], input: Option<&mut Reader>, configurator: |&mut ProcessConfig|) -> CargoResult<Process> {
+ let mut config = ProcessConfig::new();
+ config.program = program;
+ config.args = args;
+ configurator(&mut config);
+
+ println!("Executing {} {}", program, args);
+
+ let mut process = try!(Process::configure(config).to_cargo_error(~"Could not configure process", 1));
+
+ input.map(|mut reader| io::util::copy(&mut reader, process.stdin.get_mut_ref()));
+
+ Ok(process)
+}
+
--- /dev/null
+use toml;
+use hammer::FlagConfig;
+use serialize::Decoder;
+use toml::from_toml;
+use {CargoResult,ToCargoError,core};
+use std::path::Path;
+use collections::HashMap;
+use core::package::NameVer;
+use core::dependency::Dependency;
+
+#[deriving(Decodable,Encodable,Eq,Clone)]
+struct SerializedManifest {
+ project: ~core::Project,
+ lib: Option<~[SerializedLibTarget]>,
+ bin: Option<~[SerializedExecTarget]>,
+ dependencies: HashMap<~str, ~str>
+}
+
+#[deriving(Decodable,Encodable,Eq,Clone)]
+pub struct SerializedTarget {
+ name: ~str,
+ path: Option<~str>
+}
+
+pub type SerializedLibTarget = SerializedTarget;
+pub type SerializedExecTarget = SerializedTarget;
+
+
+#[deriving(Decodable,Eq,Clone,Ord)]
+pub struct ReadManifestFlags {
+ manifest_path: ~str
+}
+
+impl FlagConfig for ReadManifestFlags {}
+
+pub fn read_manifest(manifest_path: &str) -> CargoResult<core::Manifest> {
+ match execute(ReadManifestFlags { manifest_path: manifest_path.to_owned() }) {
+ Ok(manifest) => Ok(manifest.unwrap()),
+ Err(e) => Err(e)
+ }
+}
+
+pub fn execute(flags: ReadManifestFlags) -> CargoResult<Option<core::Manifest>> {
+ let manifest_path = flags.manifest_path;
+ let root = try!(toml::parse_from_file(manifest_path.clone()).to_cargo_error(format!("Couldn't parse Toml file: {}", manifest_path), 1));
+
+ let toml_manifest = try!(from_toml::<SerializedManifest>(root.clone()).to_cargo_error(|e: toml::Error| format!("Couldn't parse Toml file: {:?}", e), 1));
+
+ let (lib, bin) = normalize(&toml_manifest.lib, &toml_manifest.bin);
+
+ let SerializedManifest { project, dependencies, .. } = toml_manifest;
+
+ Ok(Some(core::Manifest {
+ root: try!(Path::new(manifest_path.clone()).dirname_str().to_cargo_error(format!("Could not get dirname from {}", manifest_path), 1)).to_owned(),
+ project: project,
+ lib: lib,
+ bin: bin,
+ dependencies: dependencies.iter().map(|(k,v)| NameVer::new(k.clone(),v.clone())).collect()
+ }))
+}
+
+fn normalize(lib: &Option<~[SerializedLibTarget]>, bin: &Option<~[SerializedExecTarget]>) -> (~[core::LibTarget], ~[core::ExecTarget]) {
+ fn lib_targets(libs: &[SerializedLibTarget]) -> ~[core::LibTarget] {
+ let l = &libs[0];
+ let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name));
+ ~[core::LibTarget { path: path, name: l.name.clone() }]
+ }
+
+ fn bin_targets(bins: &[SerializedExecTarget], default: |&SerializedExecTarget| -> ~str) -> ~[core::ExecTarget] {
+ bins.iter().map(|bin| {
+ let path = bin.path.clone().unwrap_or_else(|| default(bin));
+ core::ExecTarget { path: path, name: bin.name.clone() }
+ }).collect()
+ }
+
+ match (lib, bin) {
+ (&Some(ref libs), &Some(ref bins)) => {
+ (lib_targets(libs.as_slice()), bin_targets(bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name)))
+ },
+ (&Some(ref libs), &None) => {
+ (lib_targets(libs.as_slice()), ~[])
+ },
+ (&None, &Some(ref bins)) => {
+ (~[], bin_targets(bins.as_slice(), |bin| format!("src/{}.rs", bin.name)))
+ },
+ (&None, &None) => {
+ (~[], ~[])
+ }
+ }
+}
--- /dev/null
+use std;
+use std::os::args;
+use std::io;
+use std::io::process::{Process,ProcessConfig,InheritFd};
+use std::path::Path;
+use {CargoResult,CargoError,ToCargoError,NoFlags,core};
+
+/**
+ cargo-rustc -- ...args
+
+ Delegate ...args to actual rustc command
+*/
+
+pub fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult<Option<core::Manifest>> {
+ let core::Manifest { root, lib, bin, .. } = manifest;
+
+ let (crate_type, out_dir) = if lib.len() > 0 {
+ ( ~"lib", lib[0].path )
+ } else if bin.len() > 0 {
+ ( ~"bin", bin[0].path )
+ } else {
+ return Err(CargoError::new(~"bad manifest, no lib or bin specified", 1));
+ };
+
+ let root = Path::new(root);
+ let target = join(&root, ~"target");
+
+ let args = [
+ join(&root, out_dir),
+ ~"--out-dir", target,
+ ~"--crate-type", crate_type
+ ];
+
+ match io::fs::mkdir_recursive(&root.join("target"), io::UserRWX) {
+ Err(_) => fail!("Couldn't mkdir -p"),
+ Ok(val) => val
+ }
+
+ println!("Executing rustc {}", args.as_slice());
+
+ let mut config = ProcessConfig::new();
+ config.stdout = InheritFd(1);
+ config.stderr = InheritFd(2);
+ config.program = "rustc";
+ config.args = args.as_slice();
+
+ let mut p = try!(Process::configure(config).to_cargo_error(format!("Could not start process: rustc {}", args.as_slice()), 1));
+
+ let status = p.wait();
+
+ if status != std::io::process::ExitStatus(0) {
+ fail!("Failed to execute")
+ }
+
+ Ok(None)
+}
+
+fn join(path: &Path, part: ~str) -> ~str {
+ format!("{}", path.join(part).display())
+}
--- /dev/null
+pub mod path_source;
+pub mod cargo_compile;
+pub mod cargo_read_manifest;
+pub mod cargo_rustc;
--- /dev/null
+struct PathSourceOp;
--- /dev/null
+use core::source::{Source,PackagePath};
+use core::package::NameVer;
+use CargoResult;
+use ops::cargo_read_manifest::read_manifest;
+
+struct PathSource {
+ paths: Vec<Path>
+}
+
+impl PathSource {
+ pub fn new(paths: Vec<Path>) -> PathSource {
+ PathSource { paths: paths }
+ }
+
+ fn map<T>(&self, callback: |&Path| -> CargoResult<T>) -> CargoResult<Vec<T>> {
+ let mut ret = Vec::with_capacity(self.paths.len());
+
+ for path in self.paths.iter() {
+ ret.push(try!(callback(path)));
+ }
+
+ Ok(ret)
+ }
+}
+
+impl Source for PathSource {
+ fn update(&self) -> CargoResult<()> { Ok(()) }
+
+ fn list(&self) -> CargoResult<Vec<NameVer>> {
+ self.map(|path| {
+ let manifest = try!(read_manifest(path.as_str().unwrap()));
+ Ok(manifest.get_name_ver())
+ })
+ }
+
+ fn download(&self, name_ver: Vec<NameVer>) -> CargoResult<()>{
+ Ok(())
+ }
+
+ fn get(&self, packages: Vec<NameVer>) -> CargoResult<Vec<PackagePath>> {
+ self.map(|path| {
+ let manifest = try!(read_manifest(path.as_str().unwrap()));
+ let name_ver = manifest.get_name_ver();
+ let path = manifest.get_path();
+
+ Ok(PackagePath::new(name_ver, path))
+ })
+ }
+}